package com.lmx.persistence.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.PropertiesFileUtil;
import com.lmx.repoDomain.exception.BusinessException;
import com.lmx.repoDomain.tmodel.Bed;
import com.lmx.repoDomain.tmodel.Camera;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.CustomerDevice;
import com.lmx.repoDomain.tmodel.Device;
import com.lmx.repoDomain.tmodel.DeviceBindMore;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.HbeaconWarning;
import com.lmx.repoDomain.tmodel.PersonLocation;
import com.lmx.repoDomain.tmodel.Room;
import com.lmx.repoDomain.tmodel.Tenant;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

/**
 *
 *
 * @author huibati
 * @version 1.00
 */
@Service
@Scope("prototype")
public class DeviceService<T> {

	private Log logger = LogFactory.getLog(this.getClass());

	private Properties properties = PropertiesFileUtil.getApplicationProperties();

	@PersistenceContext
	private EntityManager em;

	@Autowired
	protected GenericService dslJpaService;

	@Autowired
	protected CommonService commonService;

	@Autowired
	protected MessageService messageService;

	// @Autowired
	// protected EmployeeService employeeService;

	@Autowired
	protected ALiService aLiService;

	/*
	 * 根据设备号取得对应的老人
	 * 
	 * @params deviceNo 设备编号
	 */
	public Customer getCustomerWithDeviceNo(String deviceNo) {
		// 取得所有对应的customer记录，取第一条
		StringBuilder query = new StringBuilder("select c from CustomerDevice cd inner join cd.customer as c  "
				+ "inner join cd.device as d where d.seq = ?1 and cd.delStatus != 1 ");
		ArrayList<Customer> customers = (ArrayList<Customer>) this.em.createQuery(query.toString())
				.setParameter(1, deviceNo).getResultList();
		if (customers.size() == 0) {
			return null;
		}
		return customers.get(0);
	}

	public Customer getCustomerWithDeviceNo(String deviceNo1, String deviceNo2) {
		// 取得所有对应的customer记录，取第一条
		StringBuilder query = new StringBuilder("select c from CustomerDevice cd inner join cd.customer as c  "
				+ "inner join cd.device as d where (d.seq = ?1 or d.seq = ?2)  and cd.delStatus != 1 ");
		ArrayList<Customer> customers = (ArrayList<Customer>) this.em.createQuery(query.toString())
				.setParameter(1, deviceNo1).setParameter(2, deviceNo2).getResultList();
		if (customers.size() == 0) {
			return null;
		}
		return customers.get(0);
	}

	/*
	 * 设备
	 * 
	 * @params deviceNo 设备编号
	 */
	public Device getDeviceWithDeviceNo(String deviceNo) {
		if (deviceNo == null || "".equals(deviceNo)) {
			return null;
		}
		// 取得所有对应的记录，取第一条
		StringBuilder query = new StringBuilder("select c from Device c where  c.seq = ?1 and c.delStatus != 1");
		ArrayList<Device> devices = (ArrayList<Device>) this.em.createQuery(query.toString()).setParameter(1, deviceNo)
				.getResultList();
		if (devices.size() == 0) {
			return null;
		}
		return devices.get(0);
	}

	/*
	 * 设备
	 * 
	 * @params
	 */
	public Device getDeviceWithId(Long id) {
		// 取得所有对应的记录，取第一条
		StringBuilder query = new StringBuilder("select c from Device c where c.id = ?1 and c.delStatus != 1");
		ArrayList<Device> devices = (ArrayList<Device>) this.em.createQuery(query.toString()).setParameter(1, id)
				.getResultList();
		if (devices.size() == 0) {
			return null;
		}
		return devices.get(0);
	}

	/*
	 * 更新设备状态时间
	 */
	public void updateDeviceStatusDate(String jsonData) {
		try {
			logger.debug("update device  status date " + jsonData);
			JSONObject data = JSONObject.fromObject(jsonData);
			JSONArray deviceData = data.getJSONArray("deviceData");
			String localFlag = data.containsKey("localFlag") ? data.getString("localFlag") : null;
			if (localFlag != null) {
				ActionContextHolder.getLocalServerFlag().put(localFlag, CommonUtil.getCurrTimes());
			}
			List<Device> deviceList = new ArrayList<>();
			List<Device> tempList = new ArrayList<>();
			Map<String, Device> deviceMap = new HashMap<>();
			StringBuilder query = new StringBuilder("select c from Device c where c.delStatus != ?1");
			deviceList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).getResultList();// 获取全部Device
			if (deviceList != null && deviceList.size() > 0) {
				for (Device device : deviceList) {
					if (device != null) {
						deviceMap.put(device.getSeq(), device);
					}
				}
				for (int i = 0; i < deviceData.size(); i++) {
					String deviceId = deviceData.getJSONObject(i).getString("deviceId");
					Integer dataTime = deviceData.getJSONObject(i).getInt("dataTime");
					if (deviceMap.containsKey(deviceId)) {
						deviceMap.get(deviceId).setStatusDate(dataTime);// 设置设备状态时间
						deviceMap.get(deviceId).setLastUpdateDateTime(CommonUtil.getCurrTimes());
						deviceMap.get(deviceId).setDeviceStatus((short) 1);
						tempList.add(deviceMap.get(deviceId));
					}
				}
			}
			if (tempList.size() > 0) {
				commonService.batchUpdate(tempList);// 批量更新
			}
		} catch (Exception e) {
			logger.debug("update device  status date error:" + e);
		}
	}

	/*
	 * 手环按键位置信息
	 */
	@Transactional
	public void updateDeviceLocationData(String jsonData) {
		try {
			logger.debug("update device  Location  date " + jsonData);
			JSONObject data = JSONObject.fromObject(jsonData);
			JSONArray deviceData = data.getJSONArray("locationData");
			List<Long> deviceIds = new ArrayList<>();
			List<CustomerDevice> deviceCustomerList = new ArrayList<>();
			List<Employee> deviceEmployeeList = new ArrayList<>();
			List<Room> roomList = new ArrayList<>();
			List<PersonLocation> plList = new ArrayList<>();
			List<PersonLocation> slList = new ArrayList<>();
			List<PersonLocation> messageList = new ArrayList<>();
			Map<String, CustomerDevice> deviceCustomerMap = new HashMap<>();
			Map<String, Employee> deviceEmployeeMap = new HashMap<>();
			Map<String, Room> deviceRoomMap = new HashMap<>();
			String localFlag = data.containsKey("localFlag") ? data.getString("localFlag") : null;
			if (localFlag != null) {
				ActionContextHolder.getLocalServerFlag().put(localFlag, CommonUtil.getCurrTimes());
			}
			deviceCustomerList = this.em
					.createQuery(
							"select c from CustomerDevice c where c.delStatus != ?1  and c.customer is not null and c.device is not null ")
					.setParameter(1, (short) 1).getResultList();// 获取全部Device
			roomList = this.em.createQuery("select c from Room c where c.delStatus != ?1 and c.scanner is not null ")
					.setParameter(1, (short) 1).getResultList();// 获取全部room
			deviceEmployeeList = this.em
					.createQuery("select c from Employee c where c.delStatus != ?1 and c.bracelet is not null ")
					.setParameter(1, (short) 1).getResultList();// 获取全部employee
			if (deviceEmployeeList != null && deviceEmployeeList.size() > 0) {
				for (Employee cd : deviceEmployeeList) {
					if (cd != null && cd.getBracelet() != null) {
						deviceEmployeeMap.put(cd.getBracelet().getSeq(), cd);// 手环以及Employeemap
					}
				}
			}
			if (deviceCustomerList != null && deviceCustomerList.size() > 0) {
				for (CustomerDevice cd : deviceCustomerList) {
					if (cd != null) {
						deviceCustomerMap.put(cd.getDevice().getSeq(), cd);// 手环以及Customermap
					}
				}
			}
			if (roomList != null && roomList.size() > 0) {
				for (Room room : roomList) {
					if (room != null && room.getScanner() != null) {
						deviceRoomMap.put(room.getScanner().getSeq(), room);// scanner以及Roommap
					}
				}
			}
			if ((deviceEmployeeMap.size() > 0 || deviceCustomerMap.size() > 0) && deviceRoomMap.size() > 0) {
				for (int i = 0; i < deviceData.size(); i++) {
					String deviceId = deviceData.getJSONObject(i).getString("deviceId");
					Integer dataTime = deviceData.getJSONObject(i).getInt("dataTime");
					String scannerId = deviceData.getJSONObject(i).getString("scanner");
					Device device = this.getDeviceWithDeviceNo(deviceId);
					if (device != null) {
						deviceIds.add(device.getId());
					}
					device = this.getDeviceWithDeviceNo(scannerId);
					if (device != null) {
						deviceIds.add(device.getId());
					}
					PersonLocation pl = new PersonLocation();
					if (deviceCustomerMap.containsKey(deviceId) && deviceRoomMap.containsKey(scannerId)) {
						// 手环为老人所用
						pl.setCustomer(deviceCustomerMap.get(deviceId).getCustomer());
						pl.setTenant(pl.getCustomer().getTenant());
						pl.setCreateDateTime(CommonUtil.getCurrTimes());
						pl.setRoom(deviceRoomMap.get(scannerId));
						pl.setLocationTime(dataTime);
						pl.setDelStatus((short) 0);
						plList.add(pl);
						messageList.add(pl);
					} else if (deviceEmployeeMap.containsKey(deviceId) && deviceRoomMap.containsKey(scannerId)) {
						// 手环为护工所用
						pl.setEmployee(deviceEmployeeMap.get(deviceId));
						pl.setTenant(pl.getEmployee().getTenant());
						pl.setCreateDateTime(CommonUtil.getCurrTimes());
						pl.setRoom(deviceRoomMap.get(scannerId));
						pl.setLocationTime(dataTime);
						pl.setDelStatus((short) 0);
						plList.add(pl);
						// slList.add(pl);
					}
				}
			}

			if (plList.size() > 0) {
				commonService.batchInsert(plList);// 批量插入
			}
			if (messageList.size() > 0) {
				for (PersonLocation pl : messageList) {
					messageService.locationRemind(pl);// 发送 Message
				}
			}
			if (deviceIds.size() > 0) { // 修改设备状态为可用状态
				StringBuilder query = new StringBuilder(
						" update Device u set u.deviceStatus = ?1 , u.lastUpdateDateTime = ?2  where  u.id in (:ids) ");
				this.em.createQuery(query.toString()).setParameter(1, (short) 1)
						.setParameter(2, CommonUtil.getCurrTimes()).setParameter("ids", deviceIds).executeUpdate();
			}
			// // 创建考勤数据
			// employeeService.createWorkTimeByLocation(slList);
		} catch (Exception e) {
			logger.debug("update device  Location date error:" + e);
		}
	}

	/**
	 * 定时 更新大耳马以及华恒 设备状态 设备时间大于当前时间100s的 就算是异常
	 */
	@Transactional
	public void updateDeviceStatus() {
		StringBuilder queryType = new StringBuilder("select c from Dicttype c  where "
				+ " c.typecode =?4 or  c.typecode =?5 or c.typecode =?6 or c.typecode =?7  ");
		List<Dicttype> typeList = this.em.createQuery(queryType.toString())
				.setParameter(4, CommonConstants.DICTTYPE.HBEACON_SCANNER.label())
				.setParameter(5, CommonConstants.DICTTYPE.HBEACON_BUTTON.label())
				.setParameter(6, CommonConstants.DICTTYPE.HBEACON_BRACELET.label())
				.setParameter(7, CommonConstants.DICTTYPE.DAERMA_BEDMAT.label()).getResultList();
		StringBuilder query = new StringBuilder(
				" update Device u set u.deviceStatus = ?1 , u.lastUpdateDateTime = ?2  where u.status.id=?3 "
						+ " and  u.delStatus!=1 " + " and  u.deviceType  in (:types) "
						+ " and  ( u.statusDate is null  or  u.statusDate < :flagTime   )");
		// 修改状态
		this.em.createQuery(query.toString()).setParameter(1, (short) 0).setParameter(2, CommonUtil.getCurrTimes())
				.setParameter(3, commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()).getId())
				.setParameter("types", typeList)
				.setParameter("flagTime", CommonUtil.getCurrTimes() - ICommonConstants.DEVICE_STATUS_FLAG)
				.executeUpdate();
	}

	/**
	 * 处理接收的大耳马推送的预警信息
	 */
	@Transactional
	public void operateDaermaWarnInfo(String jsonData) {

		List<CustomerDevice> deviceCustomerList = new ArrayList<>();
		List<HbeaconWarning> warnings = new ArrayList<>();
		List<Device> devices = new ArrayList<>();
		Map<String, CustomerDevice> deviceCustomerMap = new HashMap<>();
		StringBuilder query = new StringBuilder(
				"select c from CustomerDevice c " + " where c.delStatus != ?1  " + " and c.customer is not null "
						+ " and c.device is not null " + " and c.device.deviceType.typecode=?2 ");
		deviceCustomerList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonConstants.DICTTYPE.DAERMA_BEDMAT.label()).getResultList();// 获取全部daermaDevice
		if (deviceCustomerList != null && deviceCustomerList.size() > 0) {
			for (CustomerDevice cd : deviceCustomerList) {
				if (cd != null) {
					deviceCustomerMap.put(cd.getDevice().getSeq(), cd);// 床垫以及Customermap
				}
			} // end for deviceCustomerList
			jsonData = "[" + jsonData + "]";
			JSONArray jsonArray = JSONArray.fromObject(jsonData);
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				String infoType = jsonObject.getString("command");// 心率还是体动
				String bedMatId = jsonObject.getString("mattressId");// 床垫id
				int type = jsonObject.getInt("type");
				Integer infoDate = jsonObject.getInt("currentTime");
				if (deviceCustomerMap.containsKey(bedMatId)) {
					Device mat = deviceCustomerMap.get(bedMatId).getDevice();
					// 建立预警信息 并发送预警信息
					int insertFlag = 1;
					HbeaconWarning warning = new HbeaconWarning();
					int callTime = CommonUtil.getCurrTimes();
					warning.setCaller(deviceCustomerMap.get(bedMatId).getCustomer());
					warning.setBed(deviceCustomerMap.get(bedMatId).getCustomer().getBed());
					warning.setCallTime(callTime);
					warning.setCreateDateTime(callTime);
					warning.setDelStatus((short) 0);
					warning.setTenant(deviceCustomerMap.get(bedMatId).getCustomer().getTenant());
					if ("warn".equals(infoType)) {// 心律异常
						if (type == 1) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_1.label());
						}
						if (type == 2) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_2.label());
						}
						if (type == 3) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_3.label());
						}
						if (type == 4) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_4.label());
						}
						if (type == 5) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_5.label());
						}
						if (type == 6) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_6.label());
						}
						// 修改设备信息
						mat.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));// 已占用
						mat.setBindStatus(
								commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));// 已绑定
						devices.add(mat);
					}
					if ("mattressStatus".equals(infoType)) {// 体动异常
						if (type == 3) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_7.label());
							// 判断最近一条的是否是离床避免重复
							StringBuilder sqlFlag = new StringBuilder(
									"select c from HbeaconWarning c where c.delStatus != ?1  and c.bed.id=?2 and c.caller.id=?3  "
											+ "and ( c.reason like '%离床%' or  c.reason like '%回床%'  ) order by c.callTime desc");
							List<HbeaconWarning> dataList = this.em.createQuery(sqlFlag.toString())
									.setParameter(1, (short) 1).setParameter(2, warning.getBed().getId())
									.setParameter(3, warning.getCaller().getId()).setFirstResult(0).setMaxResults(1)
									.getResultList();
							if (dataList != null && dataList.size() > 0) {
								HbeaconWarning temp = dataList.get(0);
								if (temp.getReason().equals(warning.getReason())) {
									insertFlag = 0;
								}
							}
						}
						if (type == 4) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_8.label());
							// 判断最近一条的是否是回床避免重复
							StringBuilder sqlFlag = new StringBuilder(
									"select c from HbeaconWarning c where c.delStatus != ?1  and c.bed.id=?2 and c.caller.id=?3  "
											+ "and ( c.reason like '%离床%' or  c.reason like '%回床%'  ) order by c.callTime desc");
							List<HbeaconWarning> dataList = this.em.createQuery(sqlFlag.toString())
									.setParameter(1, (short) 1).setParameter(2, warning.getBed().getId())
									.setParameter(3, warning.getCaller().getId()).setFirstResult(0).setMaxResults(1)
									.getResultList();
							if (dataList != null && dataList.size() > 0) {
								HbeaconWarning temp = dataList.get(0);
								if (temp.getReason().equals(warning.getReason())) {
									insertFlag = 0;
								}
							}
						}
						if (type == 5) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_9.label());
						}
						if (type == 10) {
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_10.label());
						}
						if (type == 6) {
							insertFlag = 0;
							warning.setReason(CommonConstants.BEDMAT_WARNING_MESAGE.MESSAGE_11.label());
						}
						if (type == 6) {
							// 修改设备信息
							mat.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_4.label()));// 离线
							devices.add(mat);
						} else {
							// 修改设备信息
							mat.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));// 已占用
							mat.setBindStatus(
									commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));// 已绑定
							devices.add(mat);
						}
					}
					if (insertFlag == 1) {
						StringBuilder sqlHb = new StringBuilder(
								"select c from HbeaconWarning c where c.delStatus != ?1  and c.bed.id=?2 and c.caller.id=?3 and c.callTime=?4 and c.reason like '%"
										+ warning.getReason() + "%'");
						List dataList = this.em.createQuery(sqlHb.toString()).setParameter(1, (short) 1)
								.setParameter(2, warning.getBed().getId()).setParameter(3, warning.getCaller().getId())
								.setParameter(4, warning.getCallTime()).getResultList();
						if (dataList == null || dataList.size() == 0) {
							warnings.add(warning);
							messageService.warningRemind(warning, infoType);
						}
					}
				} // end contains
			} // end for jsonArray
		} // end if deviceCustomerList
		if (warnings.size() > 0) {
			commonService.batchInsert(warnings);// 建立预警信息
		}
		if (devices.size() > 0) {
			commonService.batchUpdate(devices);// 修改床垫状态
		}
	}

	/**
	 * 获取device from bed
	 */
	public List<Device> getDeviceFromBed(String name, Short deviceStatus, String deviceType, String typeCode) {
		StringBuilder query = new StringBuilder();
		// 查询床位表 按键
		query.append(" select c.button from Bed c where  c.delStatus != ?1 and c.tenant.id=?2 "
				+ "   and c.button.type.codeInfo=?5 and c.name like '%" + name + "%' ");
		if (deviceStatus != -1) {
			query.append(" and c.button.deviceStatus=" + deviceStatus);
		}
		if (!"".equals(deviceType)) {
			query.append(" and c.button.deviceType.typecode='" + deviceType + "'");
		}
		List dataList = new ArrayList<>();
		dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(5, typeCode)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取device from room
	 */
	public List<Device> getDeviceFromRoom(String name, Short deviceStatus, String deviceType, String typeCode) {
		StringBuilder query = new StringBuilder();
		// 查询房间表 scanner
		query.append("select c.scanner from Room c where  c.delStatus != ?1 and c.tenant.id=?2 "
				+ "  and c.scanner.type.codeInfo=?5 and c.name like '%" + name + "%' ");
		if (deviceStatus != -1) {
			query.append(" and c.scanner.deviceStatus=" + deviceStatus);
		}
		if (!"".equals(deviceType)) {
			query.append(" and c.scanner.deviceType.typecode='" + deviceType + "'");
		}

		List dataList = new ArrayList<>();
		dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(5, typeCode)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取device from employee
	 */
	public List<Device> getDeviceFromEmployee(String name, Short deviceStatus, String deviceType, String typeCode) {
		StringBuilder query = new StringBuilder();
		// 查询Employee表 手环
		query.append("select c.bracelet from Employee c where  c.delStatus != ?1 and c.tenant.id=?2 "
				+ " and c.bracelet.type.codeInfo=?5 and c.name like '%" + name + "%' ");
		if (deviceStatus != -1) {
			query.append(" and c.bracelet.deviceStatus=" + deviceStatus);
		}
		if (!"".equals(deviceType)) {
			query.append(" and c.bracelet.deviceType.typecode='" + deviceType + "'");
		}

		List dataList = new ArrayList<>();
		dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(5, typeCode)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取device from customer
	 */
	public List<Device> getDeviceFromCustomer(String name, Short deviceStatus, String deviceType, String typeCode) {
		// 查询CustomerDevice 客户设备关联表
		StringBuilder query = new StringBuilder(
				"select c.device from CustomerDevice c where  c.delStatus != ?1 and c.tenant.id=?2 "
						+ " and c.device.type.codeInfo=?5 and c.customer.name like '%" + name + "%'  ");
		if (deviceStatus != -1) {
			query.append(" and c.device.deviceStatus=" + deviceStatus);
		}
		if (!"".equals(deviceType)) {
			query.append(" and c.device.deviceType.typecode='" + deviceType + "'");
		}
		List dataList = new ArrayList<>();
		dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1).setParameter(5, typeCode)
				.setParameter(2, ActionContextHolder.getContext().getTenantId()).getResultList();
		return dataList;
	}

	/**
	 * 获取device from all
	 */
	public List<Device> getDeviceFromAll(String name, Short deviceStatus, String deviceType, String typeCode) {
		List dataList = new ArrayList<>();
		dataList.addAll(this.getDeviceFromCustomer(name, deviceStatus, deviceType, typeCode));
		dataList.addAll(this.getDeviceFromEmployee(name, deviceStatus, deviceType, typeCode));
		dataList.addAll(this.getDeviceFromRoom(name, deviceStatus, deviceType, typeCode));
		dataList.addAll(this.getDeviceFromBed(name, deviceStatus, deviceType, typeCode));
		return dataList;
	}

	/**
	 * 验证device是否有关联
	 */
	public int checkDeviceRelations(Device device) {
		List dataList = new ArrayList<>();
		// 查询CustomerDevice 客户设备关联表
		StringBuilder query = new StringBuilder(
				"select c.device_id from tnb_customer_device c where  c.del_status != ?1 and c.tenant_id=?3 "
						+ " and c.device_id =?2 ");
		// 查询Employee表 手环
		query.append(" union select c.bracelet_id from tnb_employee c where  c.del_status != ?1 and c.tenant_id=?3 "
				+ " and c.bracelet_id =?2 ");
		// 查询房间表 scanner
		query.append(" union select c.scanner_id from tnb_room c where  c.del_status != ?1 and c.tenant_id=?3 "
				+ " and c.scanner_id =?2 ");
		// 查询床位表 按键
		query.append(" union select c.button_id from tnb_bed c where  c.del_status != ?1 and c.tenant_id=?3 "
				+ " and c.button_id =?2 ");
		dataList = this.em.createNativeQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, device.getId()).setParameter(3, ActionContextHolder.getContext().getTenantId())
				.getResultList();
		return dataList.size();
	}

	/**
	 * 绑定或者解绑device 待改进 huibati
	 */
	@Transactional
	public void operateDeviceByFlag(Device device, Camera camera) {
		StringBuilder query = new StringBuilder();
		int braceletCustomerFlag = 1;// 手环老人 使用标识
		// 非视频设备绑定操作
		if (device != null && device.getOperateFlag() != null && device.getOperateTarget() != null
				&& (CommonConstants.DEVICE_OPERATE_CODE.BIND.label().equals(device.getOperateFlag()))) {
			long targetId = Long.parseLong(device.getOperateTarget().split("\\:")[1]);
			// 验证绑定目标已经绑定过同类设备
			if (device.getOperateTarget().contains("employee")) {
				dslJpaService.setEntityClass(Employee.class);
				Employee employee = (Employee) this.dslJpaService.findById(targetId);
				if (employee != null && employee.getBracelet() != null) {
					throw new BusinessException(null, CommonConstants.ERROR_CODE.BIND_ERROR.label(), null);
				}
				query.append(" update Employee r set r.bracelet.id =?1 where r.id =?2 ");
			}
			if (device.getOperateTarget().contains("bed:")) {
				dslJpaService.setEntityClass(Bed.class);
				Bed bed = (Bed) this.dslJpaService.findById(targetId);
				if (bed != null && bed.getButton() != null) {
					throw new BusinessException(null, CommonConstants.ERROR_CODE.BIND_ERROR.label(), null);
				}
				query.append(" update Bed r set r.button.id =?1 where r.id =?2 ");
			}
			if (device.getOperateTarget().contains("room:")) {
				dslJpaService.setEntityClass(Room.class);
				Room room = (Room) this.dslJpaService.findById(targetId);
				if (room != null && room.getScanner() != null) {
					throw new BusinessException(null, CommonConstants.ERROR_CODE.BIND_ERROR.label(), null);
				}
				query.append(" update Room r set r.scanner.id =?1 where r.id =?2 ");
			}
			if (device.getOperateTarget().contains("customer")) {
				StringBuilder queryCustomer = new StringBuilder(
						"select cd.device from CustomerDevice cd  where cd.customer.id = ?1 and cd.delStatus != 1 ");
				ArrayList<Device> devices = (ArrayList<Device>) this.em.createQuery(queryCustomer.toString())
						.setParameter(1, targetId).getResultList();
				if (devices != null) {
					for (int i = 0; i < devices.size(); i++) {
						if (device.getDeviceType().getTypecode().equals(devices.get(i).getDeviceType().getTypecode())) {
							throw new BusinessException(null, CommonConstants.ERROR_CODE.BIND_ERROR.label(), null);
						}
					}
				}
				Customer customer = new Customer();
				customer.setId(targetId);
				CustomerDevice cDevice = new CustomerDevice();
				cDevice.setCustomer(customer);
				cDevice.setDevice(device);
				cDevice.setDelStatus((short) 0);
				cDevice.setTenant(device.getTenant());
				dslJpaService.setEntityClass(CustomerDevice.class);
				dslJpaService.create(cDevice);
			}
			if (query.length() > 0) {
				this.em.createQuery(query.toString()).setParameter(1, device.getId()).setParameter(2, targetId)
						.executeUpdate();
			}
			device.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));// 业务状态使用中
			device.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));// 绑定状态绑定
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(device);
		}
		// 绑定视频设备
		if (camera != null && camera.getOperateFlag() != null && camera.getOperateTarget() != null
				&& (CommonConstants.DEVICE_OPERATE_CODE.BIND.label().equals(camera.getOperateFlag()))) {
			long targetId = Long.parseLong(camera.getOperateTarget().split("\\:")[1]);
			// 绑定视频设备
			if (camera.getOperateTarget().contains("bedId:")) {
				DeviceBindMore data = new DeviceBindMore();
				Bed bed = new Bed();
				bed.setId(targetId);
				data.setBed(bed);
				data.setCamera(camera);
				data.setDelStatus((short) 0);
				data.setTenant(camera.getTenant());
				dslJpaService.setEntityClass(DeviceBindMore.class);
				dslJpaService.create(data);
			}
			if (camera.getOperateTarget().contains("roomId:")) {
				DeviceBindMore data = new DeviceBindMore();
				Room room = new Room();
				room.setId(targetId);
				data.setRoom(room);
				data.setCamera(camera);
				data.setDelStatus((short) 0);
				data.setTenant(camera.getTenant());
				dslJpaService.setEntityClass(DeviceBindMore.class);
				dslJpaService.create(data);
			}
			camera.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));// 绑定状态绑定
			dslJpaService.setEntityClass(Camera.class);
			dslJpaService.update(camera);
		}
		// 解绑非视频设备
		if (device != null && device.getOperateFlag() != null
				&& (CommonConstants.DEVICE_OPERATE_CODE.REMOVE_BIND.label().equals(device.getOperateFlag()))) {
			List dataList = new ArrayList<>();
			if (CommonConstants.DICTTYPE.HBEACON_SCANNER.label().equals(device.getDeviceType().getTypecode())) {// scanner
				Room room = null;
				dataList = this.em.createQuery(" select c from  Room c where  c.delStatus!=1 and c.scanner.id =?1  ")
						.setParameter(1, device.getId()).getResultList();
				if (dataList != null && dataList.size() > 0) {
					room = (Room) dataList.get(0);
				}
				if (room != null) {
					room.setScanner(null);
					dslJpaService.setEntityClass(Room.class);
					dslJpaService.update(room);
				}
			}
			if (CommonConstants.DICTTYPE.HBEACON_BUTTON.label().equals(device.getDeviceType().getTypecode())) {// 按键
				Bed bed = null;
				dataList = this.em.createQuery(" select c from  Bed c where  c.delStatus!=1 and c.button.id =?1  ")
						.setParameter(1, device.getId()).getResultList();
				if (dataList != null && dataList.size() > 0) {
					bed = (Bed) dataList.get(0);
				}
				if (bed != null) {
					bed.setButton(null);
					dslJpaService.setEntityClass(Bed.class);
					dslJpaService.update(bed);
				}
			}
			if (CommonConstants.DICTTYPE.HBEACON_BRACELET.label().equals(device.getDeviceType().getTypecode())) {// 手环
				Employee employee = null;
				dataList = this.em
						.createQuery(" select c from  Employee c where  c.delStatus!=1 and c.bracelet.id =?1  ")
						.setParameter(1, device.getId()).getResultList();
				if (dataList != null && dataList.size() > 0) {
					employee = (Employee) dataList.get(0);
					braceletCustomerFlag = 0;
				}
				if (employee != null) {
					employee.setBracelet(null);
					dslJpaService.setEntityClass(Employee.class);
					dslJpaService.update(employee);
				}
			}
			if (braceletCustomerFlag == 1 && (CommonConstants.DICTTYPE.HBEACON_BRACELET.label()
					.equals(device.getDeviceType().getTypecode())
					|| CommonConstants.DICTTYPE.ETCOMM_CARD.label().equals(device.getDeviceType().getTypecode())
					|| CommonConstants.DICTTYPE.DAERMA_BEDMAT.label().equals(device.getDeviceType().getTypecode()))) {// 益体康或者大耳马或者手环
				CustomerDevice cd = null;
				dataList = this.em
						.createQuery(" select  c  from  CustomerDevice c where c.delStatus!=1 and c.device.id =?1  ")
						.setParameter(1, device.getId()).getResultList();
				if (dataList != null && dataList.size() > 0) {
					cd = (CustomerDevice) dataList.get(0);
				}
				if (cd != null) {
					cd.setDelStatus((short) 1);
					dslJpaService.setEntityClass(CustomerDevice.class);
					dslJpaService.update(cd);
				}
			}
			device.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1.label()));// 业务状态空闲
			device.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));// 绑定状态空闲
			dslJpaService.setEntityClass(Device.class);
			dslJpaService.update(device);
		}
		// 解绑视频操作
		if (camera != null && camera.getOperateFlag() != null
				&& (CommonConstants.DEVICE_OPERATE_CODE.REMOVE_BIND.label().equals(camera.getOperateFlag()))) {
			List dataList = new ArrayList<>();
			DeviceBindMore cd = null;
			dataList = this.em
					.createQuery(" select  c  from  DeviceBindMore c where c.delStatus!=1 and c.camera.id =?1  ")
					.setParameter(1, camera.getId()).getResultList();
			if (dataList != null && dataList.size() > 0) {
				cd = (DeviceBindMore) dataList.get(0);
			}
			if (cd != null) {
				cd.setDelStatus((short) 1);
				dslJpaService.setEntityClass(DeviceBindMore.class);
				dslJpaService.update(cd);
			}
			camera.setBindStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));// 绑定状态空闲
			dslJpaService.setEntityClass(Camera.class);
			dslJpaService.update(camera);
		}

	}

	/**
	 * 跟换手环的时候更新设备状态
	 *
	 * @author ytche
	 * @param employee
	 * @param oldData
	 * @date 2017年5月17日 下午6:25:50
	 */
	public void updateStatus(Employee employee, Employee oldData) {
		dslJpaService.setEntityClass(Device.class);
		if (oldData != null && oldData.getBracelet() != null) {
			Device oldDevice = (Device) this.dslJpaService.findById(oldData.getBracelet().getId());
			if (oldDevice != null) {
				oldDevice.setBindStatus(
						commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_2.label()));
				oldDevice.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_1.label()));
				dslJpaService.update(oldDevice);
			}
		}
		if (employee != null && employee.getBracelet() != null) {
			Device newDevice = (Device) this.dslJpaService.findById(employee.getBracelet().getId());
			if (newDevice != null) {
				newDevice.setStatus(commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_STATUS_2.label()));
				newDevice.setBindStatus(
						commonService.getDicttype(CommonConstants.DICTTYPE.DEVICE_BIND_STATUS_1.label()));
				dslJpaService.update(newDevice);
			}
		}
	}

	/**
	 * 获取相应硬件类别的所有设备
	 */
	public List<Device> getDeviceByDictType(Dicttype model) {
		StringBuilder query = new StringBuilder(
				"select  c from Device c where c.delStatus != ?1 and  c.deviceType.typecode=?2 ");
		List dataList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, model.getTypecode()).getResultList();
		return dataList;
	}

	/**
	 * 按键复位操作
	 */
	@Transactional
	public void resetDevice(Device device) {
		HbeaconWarning warning = (HbeaconWarning) this.em
				.createQuery(
						" select  c  from  HbeaconWarning c where c.delStatus!=1 and c.flag.typecode=?1 and c.bed.button.id =?2  ")
				.setParameter(1, "hbeaconWarningCalling").setParameter(2, device.getId()).getSingleResult();
		if (warning != null) {
			warning.setFlag(commonService.getDicttype(CommonConstants.DICTTYPE.BUTTON_STATUS_3.label()));// 人工复位
			dslJpaService.setEntityClass(HbeaconWarning.class);
			dslJpaService.update(warning);
		}
		dslJpaService.setEntityClass(Device.class);
		dslJpaService.update(device);
	}

	/**
	 * 开始直播服务
	 */
	public Device startLiveService(Device device) {
		// 加验证 domainName appName streamName 是否可用
		if (device.getViewUrl() == null || device.getLiveUrl() == null) {
			if (device.getDomainName() != null && device.getAppName() != null && device.getStreamName() != null) {
				device.setViewUrl("http://" + device.getDomainName() + "/" + device.getAppName() + "/"
						+ device.getStreamName() + ".m3u8");
				device.setLiveUrl("rtmp://video-center.alivecdn.com/" + device.getAppName() + "/"
						+ device.getStreamName() + "?vhost=" + device.getDomainName() + "/");
			} else {
				device.setErrcode(0);
				return device;
			}
		}
		// 暂停直播
		String reString = aLiService.forbidLiveStream(device.getDomainName(), device.getAppName(),
				device.getStreamName());
		if ("error".equals(reString)) {
			device.setErrcode(0);
			return device;
		}
		dslJpaService.setEntityClass(Device.class);
		dslJpaService.update(device);
		return device;
	}

	/*
	 * 更新Scanner Status
	 */
	public void updateScannerStatusData(String jsonData) {
		try {
			logger.debug("update Scanner status：" + jsonData);
			JSONObject data = JSONObject.fromObject(jsonData);
			JSONArray scannerData = data.getJSONArray("scannerStatus");
			String localFlag = data.containsKey("localFlag") ? data.getString("localFlag") : null;
			if (localFlag != null) {
				ActionContextHolder.getLocalServerFlag().put(localFlag, CommonUtil.getCurrTimes());
			}
			List<Device> scannerList = new ArrayList<>();
			List<Device> updateList = new ArrayList<>();
			Map<String, Device> scannerMap = new HashMap<>();
			StringBuilder query = new StringBuilder(
					"select c from Device c where c.delStatus != ?1 and c.deviceType.typecode = ?2");
			scannerList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
					.setParameter(2, CommonConstants.DICTTYPE.HBEACON_SCANNER.label()).getResultList();// 获取全部scanner
			if (scannerList != null && scannerList.size() > 0) {
				for (Device scanner : scannerList) {
					if (scanner != null) {
						scannerMap.put(scanner.getSeq(), scanner);
					}
				}
				for (int i = 0; i < scannerData.size(); i++) {
					String scannerId = scannerData.getJSONObject(i).getString("scanner");
					// Integer dataTime =
					// scannerData.getJSONObject(i).getInt("dataTime");
					if (scannerMap.containsKey(scannerId)) {
						if (CommonConstants.SCANNER_STATUS.ONLINE.label()
								.equals(scannerData.getJSONObject(i).getString("status"))) {
							scannerMap.get(scannerId).setDeviceStatus((short) 1);
						}
						if (CommonConstants.SCANNER_STATUS.OFFLINE.label()
								.equals(scannerData.getJSONObject(i).getString("status"))) {
							scannerMap.get(scannerId).setDeviceStatus((short) 0);
						}
						scannerMap.get(scannerId).setLastUpdateDateTime(CommonUtil.getCurrTimes());
						updateList.add(scannerMap.get(scannerId));
					}
				}
			}
			if (updateList.size() > 0) {
				commonService.batchUpdate(updateList);// 批量更新
			}
		} catch (Exception e) {
			logger.debug("update scanner status error:" + e);
		}
	}

	/**
	 * 获取所有床垫seq
	 */
	public List<CustomerDevice> getAllBedMat() {
		List<CustomerDevice> deviceCustomerList = new ArrayList<>();
		Map<String, CustomerDevice> deviceCustomerMap = new HashMap<>();
		StringBuilder query = new StringBuilder(
				"select c from CustomerDevice c " + " where c.delStatus != ?1  " + " and c.customer is not null "
						+ " and c.device is not null and c.device.delStatus != ?1  and c.customer.delStatus != ?1 "
						+ " and c.device.deviceType.typecode=?2 ");
		deviceCustomerList = this.em.createQuery(query.toString()).setParameter(1, (short) 1)
				.setParameter(2, CommonConstants.DICTTYPE.DAERMA_BEDMAT.label()).getResultList();// 获取全部daermaDevice
		return deviceCustomerList;
	}

	/**
	 * 创建摄像设备
	 */
	@Transactional
	public Device createCameraDevice(Device data) {
		dslJpaService.setEntityClass(Device.class);
		dslJpaService.create(data);
		data.setAppName("live" + data.getId());
		data.setStreamName("live" + data.getId());
		StringBuilder query = new StringBuilder("select c from Tenant c  where  c.id=?1 ");
		Tenant tenant = (Tenant) this.em.createQuery(query.toString())
				.setParameter(1, ActionContextHolder.getContext().getTenantId()).getSingleResult();
		String domainName = tenant == null || tenant.getDomainName() == null ? null : tenant.getDomainName();
		data.setDomainName(domainName);
		dslJpaService.update(data);
		return data;
	}

	/**
	 * 取得数据库中的摄像头列表
	 */
	public Camera findCameraByCode(String code) {
		String query = "select c from Camera c where c.code= ?1";
		List<Camera> l = this.em.createQuery(query).setParameter(1, code).getResultList();
		if (l.size() == 0) {
			return null;
		}
		return l.get(0);
	}
}
